package com.rocpenghua.design.proxy.cglib;

import com.rocpenghua.design.proxy.jdk.UserDao;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;

/**
 * @author pengp
 * @date 2022年07月21日 16:30
 */
public class CglibClient {
    public static void main(String[] args) {
        //在指定目录下生成动态代理类，我们可以反编译看一下里面到底是一些什么东西
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "E:/proxy");
//        test0();
        test1();

    }
    public static void test0(){
        CglibProxyFactory0 cglibProxy = new CglibProxyFactory0();
        // 增强器 jdk需要提供接口，cglib需要是非私有类，且不能处理final关键字修饰的方法
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(UserDao.class);
        //设置回调对象
        enhancer.setCallback(cglibProxy);

        UserDao proxy = (UserDao) enhancer.create();

        proxy.save();

        System.out.println("===1===");

        proxy.delete();

        System.out.println("===2===");

        proxy.saveAndDelete();

        //可以看出通过方法内部调用也走了代理。这个很好理解相当于是调用的是继承类的方法
    }
    public static void test1(){
        UserDao userDao = new UserDao();
        CglibProxyFactory1 cglibProxy = new CglibProxyFactory1(userDao);
        // 增强器 jdk需要提供接口，cglib需要是非私有类，且不能处理final关键字修饰的方法
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(UserDao.class);
        //设置回调对象
        enhancer.setCallback(cglibProxy);

        UserDao proxy = (UserDao) enhancer.create();

        proxy.save();

        System.out.println("===1===");

        proxy.delete();

        System.out.println("===2===");

        proxy.saveAndDelete();

        /**
         *  可以看到方法内部调用没有走代理
         *  invoke方法调用的对象没有增强过(target 模板对象)，
         *  invokeSuper方法调用的对象已经是增强了的(proxy 代理对象)，所以会再走一遍 MethodInterceptor的 interceptor方法，如果是个拦截器链条，就会重新在走一次拦截器链
         */
    }
}
